Below is the same program, using the pretty printed expanded listing option, and with my notes.

dim L( 4 ), M( 4 ), F$( 48 )

L is the location of the 5 robot guards. M is the memory of whether there is a diamond under where each guard is standing. F$ is the custom character set,

for X = 1 to 5
L( X - 1 ) = 20 * X + X
next X

Set the starting location for the five guards. Line them up in a nice diagonal.

Q = 100

Q is the timer. Start at 100 time units.

LV = 1

LV is level, starts at 1.

graphics 18
SC = dpeek( 88 )
CH = ( peek( 106 ) - 16 ) * 256

Set the graphics mode. Put the top of screen memory in SC. Find some space for the custom character set, put that in CH.

poke 711, 28
poke 709, 12
poke 708, 88

Set the color of the diamonds, player, and robots.  

F$ = {mess of ATASCII}
move 57344, CH, 1024
move adr( F$ ), CH + 8, 40
poke 756, CH / 256

Copy the character set to RAM at the space saved for it, CH. Replace 5 of them with our custom graphics. Switch to the custom character set.

I borrowed the graphics for the wall, player, and diamond from Bill Kendricks 10-line game MINIDASH. My 8-year-old daughter designed the robot guard on graph paper. I did the hourglass.

10 G = 0

One of just two cases where I specify an explicit line number for the parser, because we jump here at the start of each new level.

G is the number of diamonds weve collected (Got) on the current level.

for X = 0 to 239
poke SC + X, 0
next X

Clear the screen at the start of each level. Didnt have to do this, but I like the effect.

poke 710, 40 - 2 * LV

Wall color changes depending on the level.

for X = 1 to 10
poke SC + X * 20, 131
poke SC + X * 20 + 19, 131
next X
for X = 2 to 19
poke SC + X, 131
poke SC + 20 * 11 + X, 131
next X

Draw the brick walls.

P = 218
poke P + SC, 66

Player starts in the bottom right corner. Draw him in.

position 0, 0
print #6; L; LV

Print level number in the upper corner.

poke SC + 220, 69

Timer icon in the bottom left.

if LV > 4
XX = 10 - LV
else
XX = 50 - 10 * LV
endif

XX is the number of diamods to collect, which decreases on each level.

for X = 1 to XX
Z = rand( 198 ) + 20
if peek( SC + Z ) = 0
poke SC + Z, 196
else
X = X - 1
endif
next X

Choose places for the diamonds. Dont put two on the same spot.

for X = 0 to 4
M( X ) = peek( SC + L( X ) )
next X

If theres a diamond on a robot stating position, we need to know that. M is memory of what each robot is standing on. It will either be 0 (nothing) or 196 (a diamond.)

35

Here we go with the main loop of the game, at 35, the other explicitly designated line number.

for I = 0 to 4
if L( I ) = P and peek( 712 ) = 0
poke 712, 28
Q = Q - 100 * LV
sound 0, 20, 2, 8
if M( I )
G = G + 1
endif
endif
next I

Check whether each robot shares the players position. If so, show a warning color, knock off points (increasing per level), play a nasty sound. If that happens on a place where theres also a diamond, you get credit for collecting it, but no points because reasons.

Dont take away points if PEEK(712) isnt 0: this prevents penalizing the player twice for the same guard hit, because we do this check again later.

poke 712, 0
sound

Turn off the warning color and nasty sound.

for I = 0 to 4
if L( I ) < 38 - I + I * 20
N = L( I ) + 1
else
if L( I ) > 201 + I - I * 20
N = L( I ) - 1
else
if L( I ) & 1 = I & 1
N = L( I ) + 20
else
N = L( I ) - 20
endif
endif
endif
endif

This mess of ifs determines the robots clockwise movement. N is the robots New location. This is the first time Ive written a program that keeps trak of things based on their location in screen memory rather than X and Y coordinates. I kind of like it  just one number of keep track of, and easier to manipulate on screen. For this graphics mode, +20 moves a character down one line, -20 up one line.

poke SC + L( I ), M( I )

Erase the guards old position, replacing it with whats in its memory of what was there before.

M( I ) = peek( SC + N )
if M( I ) = 66
M( I ) = 0
endif

Create new memory of where its about to move to. E.g. Is there a diamond there? But not if its the player.

poke SC + N, 1
L( I ) = N

Draw the robots new location, and remember it in L.

if N = P
poke 712, 28
Q = Q - 100 * LV
sound 0, 20, 2, 8
endif

If the robot and the player share the same position, color, points, buzz again. I found it necessary to do the check before and after the robot moves, or before and after the player moves, which is basically the same thing.

next I

Guards are done moving, now its the players turn.

if S = 15
PM = 0
poke P + SC, 66
else

Player isnt moving. Just redraw him to be safe. Otherwise

if S = 7
PM = 1
endif
if S = 11
PM = -1
endif
if S = 13
PM = 20
endif
if S = 14
PM = -20
endif

Inelegant way of setting the players intended relative position based on joystick position. (I couldnt think of an elegant way.)

if ( P + PM ) mod 20 = 0 or ( P + PM + 1 ) mod 20 = 0 or P + PM < 21 or P + PM > 218
PM = 0
endif

An elegant way of keeping the player in bounds (I couldnt think of an inelegant way.)

poke P + SC, 0
P = P + PM

Erase the player, move him to his new location.

if peek( P + SC ) = 196
Q = Q + 50
G = G + 1
sound 0, 60, 10, 10
endif

If new player position has a diamond, give points, count one more Gotten diamond, play a nice sound.

poke P + SC, 66

Draw the player in the new position.

if G = XX
LV = LV + 1

Did we collect them all? Increase the level by one.

if LV = 10
if T < Q
T = Q
endif
sound
position 7, 4
print #6; YOU WIN
position 1, 5
print #6; END SCORE ; Q
position 1, 6
print #6; MAX SCORE ; T
while strig( 0 )
wend
clr
run
else
goto 10
endif
endif
endif

Did we finish level 9? Then the games over. Update Top score (T) if needed, print winning message and score. Wait for trigger to play again. This (and the corresponding version for end of game without winning, below) was the last thing I added to the program. Before I just dumped to graphics 0 to print end of game messages, but the basic parsing tool saved me enough space to squeeze in this pretty version and replay-ability with the trigger.

Q = Q - 0.6
if T < Q
T = Q
endif
position 1, 11
print #6; Q; \A3\A3\A3\A3

The game isnt over. Decrease the timer by .6 (I think seeing the decimals fly by on the timer makes it seem more frantic.) Print the timer with some brick characters after to overwrite the old numbers.

if Q <= 0
sound
position 3, 4
print #6; % GAME OVER %
position 1, 5
print #6; MAX SCORE ; T
position 1, 6
print #6; FIRE TO PLAY AGAIN
while strig( 0 )
wend
clr
run
endif

The timer has run out, print game over message and score. Trigger restarts. CLR:RUN takes less space than resetting the level to 1, timer to 100.

goto 35

Games still in progress, continue main loop.